/**
 **************************************************************************************************************************
 * 
 **************************************************************************************************************************
 * @file QRBFrame.h
 **************************************************************************************************************************/


#ifndef __QRBFRAME_H__
#define __QRBFRAME_H__

/**************************************************************************************************************************
 * Includes
 **************************************************************************************************************************/
#include <QtGui/QWidget>
#include <QtGui/QPaintEvent>
#include <RB.h>
#include <RBApplication/RBApplication.h>

/**************************************************************************************************************************
 * Forward declarations
 **************************************************************************************************************************/


/**************************************************************************************************************************
 * Classes
 **************************************************************************************************************************/
class QRBFrame : public QWidget
{
    Q_OBJECT
public:

    explicit QRBFrame(QWidget* parent = 0) 
        : QWidget(parent)
        , m_pApplication(0)
    {
        setAttribute(Qt::WA_OpaquePaintEvent);
        setAttribute(Qt::WA_PaintOnScreen);
        setMouseTracking(true);
        setFocusPolicy(Qt::WheelFocus);
    }

   ~QRBFrame() 
   {
       m_pApplication->Release();
       delete m_pApplication;
   }

   QPaintEngine * paintEngine () const { return 0; }
   virtual void paintEvent ( QPaintEvent * event )
   {
        m_pApplication->OnIdle();
        event->accept();
   }

    virtual void showEvent(QShowEvent *e)
    {
        if (!RBApplication::GetSingleton())
        {
            m_pApplication = new RBApplication(width(), height());
            m_pApplication->Init(winId());
        }

        QWidget::showEvent(e);
    }

    virtual void resizeEvent(QResizeEvent *e);

#define RBTranslateMouseFromQt(qtButtons, qtFlag, rbFlag, rbState) \
    if (qtButtons & qtFlag) m_pApplication->OnKey(rbFlag, rbState)

    virtual void mousePressEvent(QMouseEvent *e)
    {
        RBTranslateMouseFromQt(e->buttons(), Qt::LeftButton, RBInput::IK_LBUTTON, RBInput::KS_DOWN);
        RBTranslateMouseFromQt(e->buttons(), Qt::RightButton, RBInput::IK_RBUTTON, RBInput::KS_DOWN);
        RBTranslateMouseFromQt(e->buttons(), Qt::MidButton, RBInput::IK_MBUTTON, RBInput::KS_DOWN);
        e->accept();
    }

    virtual void mouseReleaseEvent(QMouseEvent *e)
    {
        RBTranslateMouseFromQt(~e->buttons(), Qt::LeftButton, RBInput::IK_LBUTTON, RBInput::KS_UP);
        RBTranslateMouseFromQt(~e->buttons(), Qt::RightButton, RBInput::IK_RBUTTON, RBInput::KS_UP);
        RBTranslateMouseFromQt(~e->buttons(), Qt::MidButton, RBInput::IK_MBUTTON, RBInput::KS_UP);
        e->accept();
    }

    virtual void mouseMoveEvent(QMouseEvent *e)
    {
        m_pApplication->SetMousePos(int2(e->x(),e->y()));
        e->accept();
    }

    virtual void keyPressEvent(QKeyEvent *e)
    {
        #define RBINPUTKEYASCII(key, value) case Qt::Key_##key: m_pApplication->OnKey(RBInput::IK_##key, RBInput::KS_DOWN); break;
        switch(e->key())
        {
            #include "RBMain/RBInputKeys.inl"
            default: break;
        }
        #undef RBINPUTKEYASCII
        e->accept();
    }

    virtual void keyReleaseEvent(QKeyEvent *e)
    {
        #define RBINPUTKEYASCII(key, value) case Qt::Key_##key: m_pApplication->OnKey(RBInput::IK_##key, RBInput::KS_UP); break;
        switch(e->key())
        {
            #include "RBMain/RBInputKeys.inl"
            default: break;
        }
        #undef RBINPUTKEYASCII
        e->accept();
    }


    RBApplication* GetRBApp() const { return m_pApplication; }

private:
    RBApplication* m_pApplication;
};

/**************************************************************************************************************************/

#endif // __QRBFRAME_H__